home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / unix / unzip51 / os2 / os2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-18  |  9.1 KB  |  445 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   os2.c
  4.  
  5.   OS/2-specific routines for use with Info-ZIP's UnZip 5.1 and later.
  6.  
  7.   This file incorporates Kai Uwe Rommel's FAT/HPFS filename translation and
  8.   extended attributes code from os2unzip.c, along with his filetime code from
  9.   file_io.c and the MSDOS/OS2/NT version of mapattr().
  10.  
  11.   ---------------------------------------------------------------------------*/
  12.  
  13.  
  14. #include "unzip.h"
  15.  
  16. #define INCL_NOPM
  17. #define INCL_DOSNLS
  18. #define INCL_DOSERRORS
  19. #include <os2.h>
  20.  
  21.  
  22. #define EAID     0x0009
  23.  
  24.  
  25. extern int tflag, quietflg;
  26.  
  27.  
  28. typedef struct
  29. {
  30.   ush nID;
  31.   ush nSize;
  32.   ulg lSize;
  33. }
  34. EAHEADER, *PEAHEADER;
  35.  
  36.  
  37. #ifndef __32BIT__
  38.  
  39. typedef struct
  40. {
  41.   ULONG oNextEntryOffset;
  42.   BYTE fEA;
  43.   BYTE cbName;
  44.   USHORT cbValue;
  45.   CHAR szName[1];
  46. }
  47. FEA2, *PFEA2;
  48.  
  49. typedef struct
  50. {
  51.   ULONG cbList;
  52.   FEA2 list[1];
  53. }
  54. FEA2LIST, *PFEA2LIST;
  55.  
  56. #endif
  57.  
  58.  
  59. #ifndef __32BIT__
  60. #define DosSetPathInfo(p1, p2, p3, p4, p5) \
  61.         DosSetPathInfo(p1, p2, p3, p4, p5, 0)
  62. #define DosQueryPathInfo(p1, p2, p3, p4) \
  63.     DosQPathInfo(p1, p2, p3, p4, 0)
  64. #define DosMapCase DosCaseMap
  65. #define DosQueryCtryInfo DosGetCtryInfo
  66. #endif
  67.  
  68.  
  69. #ifndef ZIPINFO
  70.  
  71.  
  72. extern int sflag;  /* user wants to allow spaces (e.g., "EA DATA. SF") */
  73.  
  74. void ChangeNameForFAT(char *name)
  75. {
  76.   char *src, *dst, *next, *ptr, *dot, *start;
  77.   static char invalid[] = ":;,=+\"[]<>| \t";
  78.  
  79.   if ( isalpha(name[0]) && (name[1] == ':') )
  80.     start = name + 2;
  81.   else
  82.     start = name;
  83.  
  84.   src = dst = start;
  85.   if ( (*src == '/') || (*src == '\\') )
  86.     src++, dst++;
  87.  
  88.   while ( *src )
  89.   {
  90.     for ( next = src; *next && (*next != '/') && (*next != '\\'); next++ );
  91.  
  92.     for ( ptr = src, dot = NULL; ptr < next; ptr++ )
  93.       if ( *ptr == '.' )
  94.       {
  95.         dot = ptr; /* remember last dot */
  96.         *ptr = '_';
  97.       }
  98.  
  99.     if ( dot == NULL )
  100.       for ( ptr = src; ptr < next; ptr++ )
  101.         if ( *ptr == '_' )
  102.           dot = ptr; /* remember last _ as if it were a dot */
  103.  
  104.     if ( dot && (dot > src) &&
  105.          ((next - dot <= 4) ||
  106.           ((next - src > 8) && (dot - src > 3))) )
  107.     {
  108.       if ( dot )
  109.         *dot = '.';
  110.  
  111.       for ( ptr = src; (ptr < dot) && ((ptr - src) < 8); ptr++ )
  112.         *dst++ = *ptr;
  113.  
  114.       for ( ptr = dot; (ptr < next) && ((ptr - dot) < 4); ptr++ )
  115.         *dst++ = *ptr;
  116.     }
  117.     else
  118.     {
  119.       if ( dot && (next - src == 1) )
  120.         *dot = '.';           /* special case: "." as a path component */
  121.  
  122.       for ( ptr = src; (ptr < next) && ((ptr - src) < 8); ptr++ )
  123.         *dst++ = *ptr;
  124.     }
  125.  
  126.     *dst++ = *next; /* either '/' or 0 */
  127.  
  128.     if ( *next )
  129.     {
  130.       src = next + 1;
  131.  
  132.       if ( *src == 0 ) /* handle trailing '/' on dirs ! */
  133.         *dst = 0;
  134.     }
  135.     else
  136.       break;
  137.   }
  138.  
  139.   for ( src = start; *src != 0; ++src )
  140.     if ( (strchr(invalid, *src) != NULL) ||
  141.          ((*src == ' ') && !sflag) )  /* allow spaces if user wants */
  142.         *src = '_';
  143. }
  144.  
  145.  
  146. int IsFileNameValid(char *name)
  147. {
  148.   HFILE hf;
  149. #ifdef __32BIT__
  150.   ULONG uAction;
  151. #else
  152.   USHORT uAction;
  153. #endif
  154.  
  155.   switch( DosOpen(name, &hf, &uAction, 0, 0, FILE_OPEN,
  156.                   OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0) )
  157.   {
  158.   case ERROR_INVALID_NAME:
  159.   case ERROR_FILENAME_EXCED_RANGE:
  160.     return FALSE;
  161.   case NO_ERROR:
  162.     DosClose(hf);
  163.   default:
  164.     return TRUE;
  165.   }
  166. }
  167.  
  168.  
  169. int GetCountryInfo(void)
  170. {
  171.     COUNTRYINFO ctryi;
  172.     COUNTRYCODE ctryc;
  173. #ifdef __32BIT__
  174.     ULONG cbInfo;
  175. #else
  176.     USHORT cbInfo;
  177. #endif
  178.  
  179.   ctryc.country = ctryc.codepage = 0;
  180.  
  181.   if ( DosQueryCtryInfo(sizeof(ctryi), &ctryc, &ctryi, &cbInfo) != NO_ERROR )
  182.     return 0;
  183.  
  184.   return ctryi.fsDateFmt;
  185. }
  186.  
  187.  
  188. long GetFileTime(char *name)
  189. {
  190. #ifdef __32BIT__
  191.   FILESTATUS3 fs;
  192. #else
  193.   FILESTATUS fs;
  194. #endif
  195.   USHORT nDate, nTime;
  196.  
  197.   if ( DosQueryPathInfo(name, 1, (PBYTE) &fs, sizeof(fs)) )
  198.     return -1;
  199.  
  200.   nDate = * (USHORT *) &fs.fdateLastWrite;
  201.   nTime = * (USHORT *) &fs.ftimeLastWrite;
  202.  
  203.   return ((ULONG) nDate) << 16 | nTime;
  204. }
  205.  
  206.  
  207. void SetPathInfo(char *path, ush moddate, ush modtime, int flags)
  208. {
  209.   union {
  210.     FDATE fd;               /* system file date record */
  211.     ush zdate;              /* date word */
  212.   } ud;
  213.   union {
  214.     FTIME ft;               /* system file time record */
  215.     ush ztime;              /* time word */
  216.   } ut;
  217.   FILESTATUS fs;
  218.   USHORT nLength;
  219.   char szName[CCHMAXPATH];
  220.  
  221.   strcpy(szName, path);
  222.   nLength = strlen(szName);
  223.   if (szName[nLength - 1] == '/')
  224.     szName[nLength - 1] = 0;
  225.  
  226.   if ( DosQueryPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)) )
  227.     return;
  228.  
  229.   ud.zdate = moddate;
  230.   ut.ztime = modtime;
  231.   fs.fdateLastWrite = fs.fdateCreation = ud.fd;
  232.   fs.ftimeLastWrite = fs.ftimeCreation = ut.ft;
  233.  
  234.   if ( flags != -1 )
  235.     fs.attrFile = flags; /* hidden, system, archive, read-only */
  236.  
  237.   DosSetPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs), 0);
  238. }
  239.  
  240.  
  241. typedef struct
  242. {
  243.   ULONG cbList;               /* length of value + 22 */
  244. #ifdef __32BIT__
  245.   ULONG oNext;
  246. #endif
  247.   BYTE fEA;                   /* 0 */
  248.   BYTE cbName;                /* length of ".LONGNAME" = 9 */
  249.   USHORT cbValue;             /* length of value + 4 */
  250.   BYTE szName[10];            /* ".LONGNAME" */
  251.   USHORT eaType;              /* 0xFFFD for length-preceded ASCII */
  252.   USHORT eaSize;              /* length of value */
  253.   BYTE szValue[CCHMAXPATH];
  254. }
  255. FEALST;
  256.  
  257.  
  258. int SetLongNameEA(char *name, char *longname)
  259. {
  260.   EAOP eaop;
  261.   FEALST fealst;
  262.  
  263.   eaop.fpFEAList = (PFEALIST) &fealst;
  264.   eaop.fpGEAList = NULL;
  265.   eaop.oError = 0;
  266.  
  267.   strcpy(fealst.szName, ".LONGNAME");
  268.   strcpy(fealst.szValue, longname);
  269.  
  270.   fealst.cbList  = sizeof(fealst) - CCHMAXPATH + strlen(fealst.szValue);
  271.   fealst.cbName  = (BYTE) strlen(fealst.szName);
  272.   fealst.cbValue = sizeof(USHORT) * 2 + strlen(fealst.szValue);
  273.  
  274. #ifdef __32BIT__
  275.   fealst.oNext   = 0;
  276. #endif
  277.   fealst.fEA     = 0;
  278.   fealst.eaType  = 0xFFFD;
  279.   fealst.eaSize  = strlen(fealst.szValue);
  280.  
  281.   return DosSetPathInfo(name, FIL_QUERYEASIZE,
  282.                         (PBYTE) &eaop, sizeof(eaop), 0);
  283. }
  284.  
  285.  
  286. int IsEA(void *extra_field)
  287. {
  288.   EAHEADER *pEAblock = (PEAHEADER) extra_field;
  289.   return extra_field != NULL && pEAblock -> nID == EAID;
  290. }
  291.  
  292.  
  293. void SetEAs(char *path, void *eablock)
  294. {
  295.   EAHEADER *pEAblock = (PEAHEADER) eablock;
  296. #ifdef __32BIT__
  297.   EAOP2 eaop;
  298.   PFEA2LIST pFEA2list;
  299. #else
  300.   EAOP eaop;
  301.   PFEALIST pFEAlist;
  302.   PFEA pFEA;
  303.   PFEA2LIST pFEA2list;
  304.   PFEA2 pFEA2;
  305.   ULONG nLength2;
  306. #endif
  307.   USHORT nLength;
  308.   char szName[CCHMAXPATH];
  309.  
  310.   if ( !IsEA(eablock) )
  311.     return;
  312.  
  313.   strcpy(szName, path);
  314.   nLength = strlen(szName);
  315.   if (szName[nLength - 1] == '/')
  316.     szName[nLength - 1] = 0;
  317.  
  318.   if ( (pFEA2list = (PFEA2LIST) malloc((size_t) pEAblock -> lSize)) == NULL )
  319.     return;
  320.  
  321.   if ( memextract((char *) pFEA2list, pEAblock -> lSize,
  322.               (char *) (pEAblock + 1), 
  323.           pEAblock -> nSize - sizeof(pEAblock -> lSize)) )
  324.   {
  325.     free(pFEA2list);
  326.     return;
  327.   }
  328.  
  329. #ifdef __32BIT__
  330.   eaop.fpGEA2List = NULL;
  331.   eaop.fpFEA2List = pFEA2list;
  332. #else
  333.   pFEAlist  = (PVOID) pFEA2list;
  334.   pFEA2 = pFEA2list -> list;
  335.   pFEA  = pFEAlist  -> list;
  336.  
  337.   do
  338.   {
  339.     nLength2 = pFEA2 -> oNextEntryOffset;
  340.     nLength = sizeof(FEA) + pFEA2 -> cbName + 1 + pFEA2 -> cbValue;
  341.  
  342.     memcpy(pFEA, (PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset), nLength);
  343.  
  344.     pFEA2 = (PFEA2) ((PCH) pFEA2 + nLength2);
  345.     pFEA = (PFEA) ((PCH) pFEA + nLength);
  346.   }
  347.   while ( nLength2 != 0 );
  348.  
  349.   pFEAlist -> cbList = (PCH) pFEA - (PCH) pFEAlist;
  350.  
  351.   eaop.fpGEAList = NULL;
  352.   eaop.fpFEAList = pFEAlist;
  353. #endif
  354.  
  355.   eaop.oError = 0;
  356.   DosSetPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &eaop, sizeof(eaop), 0);
  357.  
  358.   if (!tflag && (quietflg < 2))
  359.     printf(" (%ld bytes EA's)", pFEA2list -> cbList);
  360.  
  361.   free(pFEA2list);
  362. }
  363.  
  364.  
  365. ulg SizeOfEAs(void *extra_field)
  366. {
  367.   EAHEADER *pEAblock = (PEAHEADER) extra_field;
  368.  
  369.   if ( extra_field != NULL && pEAblock -> nID == EAID )
  370.     return pEAblock -> lSize;
  371.  
  372.   return 0;
  373. }
  374.  
  375. int mapattr()
  376. {
  377.     /* set archive bit (file is not backed up): */
  378.     pInfo->file_attr = (unsigned)crec.external_file_attributes | 32;
  379.     return 0;
  380. }
  381.  
  382. void set_file_time_and_close()
  383. {
  384.     /* don't set the time stamp on standard output */
  385.     if (cflag) {
  386.         close(outfd);
  387.         return;
  388.     }
  389.     close(outfd);
  390.  
  391.     /* set date/time and permissions */
  392.     SetPathInfo(filename, lrec.last_mod_file_date,
  393.                           lrec.last_mod_file_time, pInfo->file_attr);
  394.     if (extra_field)
  395.         SetEAs(filename, extra_field);
  396.     if (longname)
  397.         SetLongNameEA(filename, longfilename);
  398. }
  399.  
  400. #endif /* !ZIPINFO */
  401.  
  402.  
  403. static unsigned char cUpperCase[256], cLowerCase[256];
  404. static BOOL bInitialized;
  405.  
  406. static void InitNLS(void)
  407. {
  408.   unsigned nCnt, nU;
  409.   COUNTRYCODE cc;
  410.  
  411.   bInitialized = TRUE;
  412.  
  413.   for ( nCnt = 0; nCnt < 256; nCnt++ )
  414.     cUpperCase[nCnt] = cLowerCase[nCnt] = (unsigned char) nCnt;
  415.  
  416.   cc.country = cc.codepage = 0;
  417.   DosMapCase(sizeof(cUpperCase), &cc, (PCHAR) cUpperCase);
  418.  
  419.   for ( nCnt = 0; nCnt < 256; nCnt++ )
  420.   {
  421.     nU = cUpperCase[nCnt];
  422.     if (nU != nCnt && cLowerCase[nU] == (unsigned char) nU)
  423.       cLowerCase[nU] = (unsigned char) nCnt;
  424.   }
  425.  
  426.   for ( nCnt = 'A'; nCnt <= 'Z'; nCnt++ )
  427.     cLowerCase[nCnt] = (unsigned char) (nCnt - 'A' + 'a');
  428. }
  429.  
  430.  
  431. int IsUpperNLS(int nChr)
  432. {
  433.   if (!bInitialized)
  434.     InitNLS();
  435.   return (cUpperCase[nChr] == (unsigned char) nChr);
  436. }
  437.  
  438.  
  439. int ToLowerNLS(int nChr)
  440. {
  441.   if (!bInitialized)
  442.     InitNLS();
  443.   return cLowerCase[nChr];
  444. }
  445.